package conf

import (
	"context"
	"os"
	"path/filepath"
	"sync"

	"gitee.com/byx_darwin/go-tools/config/db"
	"gitee.com/byx_darwin/go-tools/config/hertz"
	"gitee.com/byx_darwin/go-tools/config/kitex"
	"gitee.com/byx_darwin/uptrace-opentelemetry/log"
	"github.com/bytedance/go-tagexpr/v2/validator"
	"github.com/cloudwego/hertz/pkg/common/hlog"
	"gopkg.in/yaml.v3"
)

var (
	conf             *Config
	once             sync.Once
	TableTablePrefix = ""
)

type Config struct {
	ServerOption hertz.ServerConfig `json:"server_option" yaml:"server_option"` //服务名称配置
	ClientOption ClientOption       `json:"client_option" yaml:"client_option"` //客户端配置
	DBOption     db.Config          `json:"db_option" yaml:"db_option"`         //DB数据库配置
	LogOption    log.Config         `json:"log_option" yaml:"log_option"`       //日志配置
	SystemConfig SystemConfig       `json:"system_config" yaml:"system_config"` //系统配置
}
type ClientOption struct {
	UserOption    kitex.ClientConfig `json:"user_option" yaml:"user_option"`
	AppOption     kitex.ClientConfig `json:"app_option" yaml:"app_option"`
	CaptchaOption kitex.ClientConfig `json:"captcha_option" yaml:"captcha_option"`
}

type SystemConfig struct {
	Captcha         Captcha `json:"captcha" yaml:"captcha"` //验证码配置
	Jwt             Jwt     `json:"jwt" yaml:"jwt"`         //jwt 配置
	HttpSignExpire  int64   `json:"http_sign_expire" yaml:"http_sign_expire"`
	DefaultPassword string  `json:"default_password" yaml:"default_password"` //默认密码
}
type Jwt struct {
	BufferTime  int    `yaml:"buffer_time" yaml:"buffer_time"`
	ExpiresTime int    `yaml:"expires_time" yaml:"expires_time"`
	Issuer      string `yaml:"issuer" yaml:"issuer"`
	SigningKey  string `yaml:"signing_key" yaml:"signing_key"`
}

// Captcha is the configuration of the captcha.
type Captcha struct {
	KeyLong          int `json:"key_long" yaml:"key_long"`
	ImgWidth         int `json:"img_width" yaml:"img_width"`
	ImgHeight        int `json:"img_height" yaml:"img_height"`
	CacheLength      int `json:"cache_length" yaml:"cache_length"`
	CacheExpiresTime int `json:"cache_expires_time" yaml:"cache_expires_time"`
}

// GetConf gets configuration instance
func GetConf() *Config {
	once.Do(initConf)
	return conf
}

func initConf() {
	ctx := context.Background()
	prefix := "conf"
	confFileRelPath := filepath.Join(prefix, filepath.Join(GetEnv(), "conf.yaml"))
	content, err := os.ReadFile(confFileRelPath)
	if err != nil {
		hlog.CtxFatalf(ctx, "read config file error - %v", err)
	}
	conf = new(Config)
	err = yaml.Unmarshal(content, conf)
	if err != nil {
		hlog.CtxFatalf(ctx, "parse yaml error - %v", err)
	}
	if err := validator.Validate(conf); err != nil {
		hlog.CtxFatalf(ctx, "validate config error - %v", err)
	}
	TableTablePrefix = conf.DBOption.TablePrefix
}

func GetEnv() string {
	e := os.Getenv("GO_ENV")
	if len(e) == 0 {
		return "dev"
	}
	return e
}
